#include "UTHObject.h"
#include "UTHArray.h"
#include "UTHString.h"
#include "UTHUndefined.h"

namespace phnq
{
	namespace uth
	{
		UTHObject::UTHObject() : UTHValue(UTH_VALUE_TYPE_OBJECT)
		{
		}
	
		UTHObject::~UTHObject()
		{
			for(map<string,UTHValue*>::iterator it=values.begin(); it != values.end(); it++)
			{
				it->second->release();
			}
		}

		void UTHObject::set(string key, string value)
		{
			UTHString *str = new UTHString(value.c_str());
			set(key, str);
			str->release();
		}

		void UTHObject::set(string key, UTHValue *value)
		{
			UTHValue *val = values[key];

			boost::mutex::scoped_lock scoped_lock(writeMutex);

			values[key] = value;
		
			if(val)
			{
				if(val != value)
				{
					val->release();
					value->retain();
				}
			}
			else
			{
				value->retain();
			}
		}

		UTHValue* UTHObject::get(string key)
		{
			UTHValue *val = values[key];
			if(val)
				return val;
			else
				return UTHUndefined::getInstance();
		}

		vector<string> UTHObject::getKeys()
		{
			vector<string> keys;
		
			for(map<string,UTHValue*>::iterator it=values.begin(); it != values.end(); it++)
			{
				keys.push_back(it->first);
			}
		
			return keys;
		}

		void UTHObject::serialize(stringbuf *sb)
		{
			vector<string> keys = getKeys();
		
			sb->sputc('{');
			bool first = true;
		
			for(int i=0; i<keys.size(); i++)
			{
				if(first)
					first = false;
				else
					sb->sputc(',');
				
				string key = keys[i];
				UTHValue *val = get(key);
			
				sb->sputc('"');
				sb->sputn(key.c_str(), key.length());
				sb->sputc('"');
				sb->sputc(':');
				val->serialize(sb);
			}
			sb->sputc('}');
		}
	}
}
